package com.mrjy.common.util;

import java.util.HashMap;
import java.util.Map;


import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;


import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import com.tencent.common.MD5;


/**
 * @author Javin
 * @date 2018年3月26日
 * @desc 
 * 1、	web授权加密：播放代码中添加ts和sign参数。当移动端WEB浏览器请求m3u8时，会在m3u8地址后面附带ts和sign参数，
 * 		POLYV云平台接收到参数后会对ts和sign参数进行校验。若校验通过，返回正确的解密密钥key文件链接给客户端。
 * 2、	token是针对PC端的html5播放器
 * 3、	APP授权需要加载SDK,移动web网页无法播放
 */
public class PolyvTokenUtil implements Cloneable {
    //polyv 提供的服务器间的通讯验证  vid.substring(0, 10)
    private static String POLYV_USERID = "04a9462273";
    //polyv 提供的接口调用签名访问的key
    private static String SECRETKEY = "PjA77ou6Yi";
    private static PolyvTokenUtil polyvTokenUtil = new PolyvTokenUtil();
    //test
//    private static String POLYV_USERID ="24b9d2e18b";
    //test
//	private static String  SECRETKEY = "FuWac0KHNp";

    //视频对应vid
	private String videoId;
	// 时间戳
	private long ts;
	// 用户 ip
	private String viewerIp;
	// 自定义用户 id
	private String viewerId;
	// 用户昵称
	private String viewerName;
	// 自定义参数
	private String extraParams;
	
	/* 将参数 $userId、$secretkey、$videoId、$ts、$viewerIp、$viewerIp、$viewerId、$viewerName、$extraParams
	    按照ASCKII升序 key + value + key + value ... +value 拼接
	*/
	//再首尾加上 secretkey
	private String plain = "";
	
	// 签名,取大写MD5
	private String sign_fortoken;
	private String sign;
	
	// 然后将下列参数用post请求  https://hls.videocc.net/service/v1/token 获取 token
	private static String URL = "https://hls.videocc.net/service/v1/token";
	
	//保利卫视资源删除路径
	private static String PolyURL = "http://api.polyv.net/v2/video/"+POLYV_USERID+"/del-video";
	//保利威视diy目录空间数据查询路径
	private static String PolySourceDiyURL = "http://api.polyv.net/v2/cata/size?";
    private PolyvTokenUtil() {
    }

    private PolyvTokenUtil(String videoId, String viewerIp, String viewerId, String viewerName,
                           String extraParams) {
		setVideoId(videoId);
		setViewerIp(viewerIp);
		setViewerId(viewerId);
		setViewerName(viewerName);
		setExtraParams(extraParams);
		setTs(System.currentTimeMillis());
		
		setPlain(SECRETKEY +"extraParams" + extraParams + "ts" + ts + "userId" + POLYV_USERID + "videoId"
				+ videoId + "viewerId" + viewerId + "viewerIp" + viewerIp + "viewerName" + viewerName+ SECRETKEY);

        System.out.println("===>" + SECRETKEY + videoId + this.ts);
        // 取大写MD5
        setSign(MD5.MD5Encode(SECRETKEY + videoId + this.ts));
        System.out.println("==sign==>"+this.sign);
		setSign_fortoken(MD5.MD5Encode(plain).toUpperCase());
	}

    public static PolyvTokenUtil clonePolyInfo(String videoId, String audioId, String viewerIp, String viewerId, String viewerName,
                                               String extraParams) throws CloneNotSupportedException {
        if (viewerId == null) {
            return null;
        }
        if (audioId == null && videoId == null) {
            return null;
        }
        videoId = videoId != null ? videoId : audioId;
        PolyvTokenUtil polyvTokenUtil_child = (PolyvTokenUtil) polyvTokenUtil.clone();
        polyvTokenUtil_child.setVideoId(videoId);
        polyvTokenUtil_child.setViewerIp(viewerIp);
        polyvTokenUtil_child.setViewerId(viewerId);
        polyvTokenUtil_child.setViewerName(viewerName);
        polyvTokenUtil_child.setExtraParams(extraParams);
        polyvTokenUtil_child.setTs(System.currentTimeMillis());

        polyvTokenUtil_child.setPlain(SECRETKEY + "extraParams" + extraParams + "ts" + polyvTokenUtil_child.ts + "userId" + POLYV_USERID + "videoId"
                + videoId + "viewerId" + viewerId + "viewerIp" + viewerIp + "viewerName" + viewerName + SECRETKEY);

        System.out.println("===>" + SECRETKEY + videoId + polyvTokenUtil_child.ts);
        // 取大写MD5
        polyvTokenUtil_child.setSign(MD5.MD5Encode(SECRETKEY + videoId + polyvTokenUtil_child.ts));
        System.out.println("==sign==>" + polyvTokenUtil_child.sign);
        polyvTokenUtil_child.setSign_fortoken(MD5.MD5Encode(polyvTokenUtil_child.plain).toUpperCase());
        return polyvTokenUtil_child;
    }

    public static PolyvTokenUtil cloneSimplePolyInfo(String videoId, String audioId, String viewerIp, String viewerId, String viewerName,
                                                     String extraParams) throws CloneNotSupportedException {
        if (viewerId == null) {
            return null;
        }
        if (audioId == null && videoId == null) {
            return null;
        }
        videoId = videoId != null ? videoId : audioId;
        PolyvTokenUtil polyvTokenUtil_child = (PolyvTokenUtil) polyvTokenUtil.clone();
        polyvTokenUtil_child.setTs(System.currentTimeMillis());

        System.out.println("===>" + SECRETKEY + videoId + polyvTokenUtil_child.ts);
        // 取大写MD5
        polyvTokenUtil_child.setSign(MD5.MD5Encode(SECRETKEY + videoId + polyvTokenUtil_child.ts));
        System.out.println("==sign==>" + polyvTokenUtil_child.sign);

        return polyvTokenUtil_child;
    }
	public static  Object deleteSource(String code) throws CloneNotSupportedException{
		Map<String, String> map = new HashMap<String, String>();
		PolyvTokenUtil polyvTokenUtil_child = (PolyvTokenUtil) polyvTokenUtil.clone();
		if(code == null){
			map.put("err_code", "201");
			map.put("err_msg", "刪除的视频id不能为空");
			return map;
		}
		long ptimeString = new Date().getTime();
		polyvTokenUtil_child.setSign(sha1("ptime="+ptimeString+"&vid="+code+SECRETKEY).toUpperCase());
		map.put("vid", code);
		map.put("ptime",""+ptimeString+"");
		map.put("sign", polyvTokenUtil_child.getSign());
		Object data = HttpUtil.doPost(PolyURL, map);
		JSONObject jsonObj = JSONObject.fromObject(data);
		return jsonObj;
	}
	public static  Object querySource(String cataid) throws CloneNotSupportedException{
		PolyvTokenUtil polyvTokenUtil_child = (PolyvTokenUtil) polyvTokenUtil.clone();
		long ptimeString = new Date().getTime();
		polyvTokenUtil_child.setSign(sha1("cataid="+cataid+"&ptime="+ptimeString+"&userid="+POLYV_USERID+SECRETKEY).toUpperCase());
		String data = HttpUtil.doGet(PolySourceDiyURL+"userid="+POLYV_USERID+"&cataid="+cataid+"&sign="+polyvTokenUtil_child.getSign()+"&ptime="+ptimeString);
		JSONObject jsonObj = JSONObject.fromObject(data);
		return jsonObj;
	}
	
	public String getPolyvToken(){
		Map<String, String> params = new HashMap<String, String>();
		params.put("userId", POLYV_USERID);
		params.put("videoId", videoId);
		params.put("ts", ts+"");
		params.put("viewerIp", viewerIp);
		params.put("viewerName", viewerName);
		params.put("extraParams", extraParams);
		params.put("viewerId", viewerId);
		params.put("sign", sign_fortoken);

        if (videoId == null) {
            return "";
        }
        String data = HttpUtil.doPost(URL, params);
        if (StringUtils.isBlank(data)) {
            return "";
        }
        JSONObject jsonObj = JSONObject.fromObject(data);
        if (jsonObj.get("code") != null && jsonObj.get("code").equals(200)) {
            if (jsonObj.get("data") != null && !jsonObj.get("data").equals("null")) {
                return (String) ((JSONObject) jsonObj.get("data")).get("token");
            }
        }
        return "";
    }
	public static String sha1(String str){
		 String sha1 = "";
		    try
		    {
		        MessageDigest crypt = MessageDigest.getInstance("SHA-1");
		        crypt.reset();
		        crypt.update(str.getBytes("UTF-8"));
		        sha1 = byteToHex(crypt.digest());
		    }
		    catch(NoSuchAlgorithmException e)
		    {
		        e.printStackTrace();
		    }
		    catch(UnsupportedEncodingException e)
		    {
		        e.printStackTrace();
		    }
		    return sha1;
	}
	private static String byteToHex(final byte[] hash)
	{
	    Formatter formatter = new Formatter();
	    for (byte b : hash)
	    {
	        formatter.format("%02x", b);
	    }
	    String result = formatter.toString();
	    formatter.close();
	    return result;
	}
	
    public static String getPOLYV_USERID() {
		return POLYV_USERID;
	}
	public static void setPOLYV_USERID(String pOLYV_USERID) {
		POLYV_USERID = pOLYV_USERID;
	}
	public static String getSECRETKEY() {
		return SECRETKEY;
	}
	public String getVideoId() {
		return videoId;
	}
	public void setVideoId(String videoId) {
		this.videoId = videoId;
	}
	public long getTs() {
		return ts;
	}
	public void setTs(long ts) {
		this.ts = ts;
	}
	public String getViewerIp() {
		return viewerIp;
	}
	public void setViewerIp(String viewerIp) {
		this.viewerIp = viewerIp;
	}
	public String getViewerId() {
		return viewerId;
	}
	public void setViewerId(String viewerId) {
		this.viewerId = viewerId;
	}
	public String getViewerName() {
		return viewerName;
	}
	public void setViewerName(String viewerName) {
		this.viewerName = viewerName;
	}
	public String getExtraParams() {
		return extraParams;
	}
	public void setExtraParams(String extraParams) {
		this.extraParams = extraParams;
	}
	public String getPlain() {
		return plain;
	}
	public void setPlain(String plain) {
		this.plain = plain;
	}
	public String getSign() {
		return sign;
	}
	public void setSign(String sign) {
		this.sign = sign;
	}
	
	public String getSign_fortoken() {
		return sign_fortoken;
	}
	public void setSign_fortoken(String sign_fortoken) {
		this.sign_fortoken = sign_fortoken;
	}

	public static void main(String[] args) {

//		PolyvTokenUtil util = new PolyvTokenUtil("24b9d2e18b77620d8efd10dcc4a89ad8_2",
//				Util.getHostIp(Util.getInetAddress()), "35", "test", "test");
//		String token = util.getPolyvToken();
//		String sign = util.getSign();
//		long ts = util.getTs();
//		System.out.println("token:"+token);
//		System.out.println("sign:"+sign);
//		System.out.println("ts:"+ts);
		long ptimeString = new Date().getTime();
		String vlue = sha1("cataid=1546567456575&ptime="+ptimeString+"&userid="+POLYV_USERID+SECRETKEY).toUpperCase();
	
		String data = HttpUtil.doGet(PolySourceDiyURL+"userid="+POLYV_USERID+"&cataid=1546567456575&sign="+vlue+"&ptime="+ptimeString);
		JSONObject jsonObj = JSONObject.fromObject(data);
		
		
		
		System.out.println(jsonObj);

	}

}
